package com.ruicar.afs.cloud.manage.common.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruicar.afs.cloud.common.core.constant.CommonConstants;
import com.ruicar.afs.cloud.common.core.enums.AfsEnumUtil;
import com.ruicar.afs.cloud.common.core.exception.AfsBaseException;
import com.ruicar.afs.cloud.common.core.security.util.SecurityUtils;
import com.ruicar.afs.cloud.common.modules.contract.enums.*;
import com.ruicar.afs.cloud.common.util.EmptyUtils;
import com.ruicar.afs.cloud.manage.clearance.vo.CostExemptBillManageVo;
import com.ruicar.afs.cloud.manage.common.entity.ManageCostExemptBill;
import com.ruicar.afs.cloud.manage.common.mapper.ManageCostExemptBillMapper;
import com.ruicar.afs.cloud.manage.common.service.ComAttachementFileService;
import com.ruicar.afs.cloud.manage.common.service.ManageCostExemptBillService;
import com.ruicar.afs.cloud.manage.common.util.CreatCaseNoUtil;
import com.ruicar.afs.cloud.manage.workflow.entity.WorkTaskCreatedInfo;
import com.ruicar.afs.cloud.manage.workflow.enums.NormalSubmitEnum;
import com.ruicar.afs.cloud.manage.workflow.enums.WorkflowTypeEnum;
import com.ruicar.afs.cloud.manage.workflow.processor.ContractWorkFlowSaveApproveInfoProcessor;
import com.ruicar.afs.cloud.manage.workflow.service.WorkTaskCreatedInfoService;
import com.ruicar.afs.cloud.manage.workflow.service.WorkflowSubmitService;
import com.ruicar.afs.cloud.manage.workflow.vo.TaskSubmitVO;
import com.ruicar.afs.cloud.workflow.api.dto.flowprocess.request.StartFlowRequest;
import com.ruicar.afs.cloud.workflow.gwt.service.WorkflowService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author: Lee
 * @date 2020-05-30 04:45:15
 * @description 费用豁免单service实现类
 */
@Service
@Slf4j
@AllArgsConstructor
public class ManageCostExemptBillServiceImpl extends ServiceImpl<ManageCostExemptBillMapper, ManageCostExemptBill> implements ManageCostExemptBillService {

    private final WorkflowSubmitService workflowSubmitService;
    private final ContractWorkFlowSaveApproveInfoProcessor saveApproveInfoProcessor;
    private final WorkflowService workflowService;
    private final WorkTaskCreatedInfoService workTaskCreatedInfoService;
    private final ComAttachementFileService comAttachementFileService;

    @Override
    public CostExemptBillManageVo addCostExemptBill(CostExemptBillManageVo vo) {

        if (vo.getId() == null) {
            //生成案件编号
            vo.setCaseNo(CreatCaseNoUtil.GeneratorCaseNo(ContractBusinessEnum.costExemptBill));
            ManageCostExemptBill one = getOne(Wrappers.<ManageCostExemptBill>query().lambda()
                    .eq(ManageCostExemptBill::getContractNo, vo.getContractNo())
                    .eq(ManageCostExemptBill::getProcessStatus,ProcessStatusEnum.draft)
            );
            if (EmptyUtils.isNotEmpty(one)){
                throw new AfsBaseException("同一个合同号不能存在两个豁免单草稿状态");
            }
            vo.setProcessStatus(ProcessStatusEnum.draft);
            vo.setApplyDate(DateUtil.date());
            vo.setStatus(CostExemptBillStatusEnum.invalid);
            vo.setApplyBy(SecurityUtils.getUser().getUserRealName());
            save(vo);
            return  vo;
        } else {
            ManageCostExemptBill byId = getById(vo.getId());
            comAttachementFileService.saveFile(vo.getContractNo(), vo.getCaseNo(),
                    ContractBusinessEnum.costExemptBill.name());
            comAttachementFileService.saveFile(vo.getContractNo(), vo.getCaseNo(),
                    ContractBusinessEnum.costExemptBill.name());
            if (!byId.getProcessStatus().equals(ProcessStatusEnum.draft) && !byId.getProcessStatus().equals(ProcessStatusEnum.toBeRepaired)) {
                throw new AfsBaseException(CommonConstants.FAIL, "此合同编号已流程中！");
            }

            updateById(byId);
            BeanUtils.copyProperties(byId,vo);
            return vo;
        }

    }

    @Override
    public void submitCostExemptBill(CostExemptBillManageVo vo) {
        if (vo.getCaseNo() == null) {
            throw new AfsBaseException(CommonConstants.FAIL, "豁免单信息请保存");
        }
        ManageCostExemptBill manageCostExemptBill = getOne(Wrappers.<ManageCostExemptBill>query().lambda()
                .eq(ManageCostExemptBill::getCaseNo, vo.getCaseNo())
        );
        if (manageCostExemptBill.getProcessStatus() != ProcessStatusEnum.draft &&
                manageCostExemptBill.getProcessStatus() != ProcessStatusEnum.toBeRepaired) {
            throw new AfsBaseException(CommonConstants.FAIL, "此合同编号已流程中！");
        }
        if (manageCostExemptBill.getProcessStatus().equals(ProcessStatusEnum.draft)) {
            manageCostExemptBill.setProcessStatus(ProcessStatusEnum.underReview);
            manageCostExemptBill.setId(manageCostExemptBill.getId());
            manageCostExemptBill.setStatus(CostExemptBillStatusEnum.approval);
            updateById(manageCostExemptBill);
            StartFlowRequest startFlowRequest = new StartFlowRequest();
            startFlowRequest.setFlowName((StringUtils.isEmpty(vo.getClientName())?"":(vo.getClientName())+"-")+AfsEnumUtil.desc(WorkflowTypeEnum.COST_EXEMTP_BILL));
            startFlowRequest.setBizDataId(String.valueOf(vo.getId()));
            startFlowRequest.setAfsFlowKey(AfsEnumUtil.key(WorkflowTypeEnum.COST_EXEMTP_BILL));
            String jsonString = JSONObject.toJSONString(vo);
            JSONObject jsonObject = JSONObject.parseObject(jsonString);
            //保存审批记录
            //保存代办任务
            saveApproveInfoProcessor.saveApproveInfo(vo, ContractBusinessEnum.costExemptBill, CaseStatusEnum.UNDER_REVIEW, BusinessUrlEnum.COST_EXEMPT_BILL);
            TaskSubmitVO taskSubmitVO = new TaskSubmitVO();
            taskSubmitVO.setBizData(jsonObject);
            workflowSubmitService.saveRecord(taskSubmitVO, AfsEnumUtil.desc(NormalSubmitEnum.SUGGEST_CHECK_FINAL));
            workflowService.startWorkFlow(startFlowRequest, jsonObject);
        } else {
            manageCostExemptBill.setProcessStatus(ProcessStatusEnum.repairedUnderReview);
            manageCostExemptBill.setId(vo.getId());
            manageCostExemptBill.setStatus(CostExemptBillStatusEnum.approval);
            updateById(manageCostExemptBill);
            StartFlowRequest startFlowRequest = new StartFlowRequest();
            startFlowRequest.setAfsFlowKey(AfsEnumUtil.key(WorkflowTypeEnum.COST_EXEMTP_BILL));
            startFlowRequest.setBizDataId(String.valueOf(vo.getId()));
            startFlowRequest.setFlowName(AfsEnumUtil.desc(WorkflowTypeEnum.COST_EXEMTP_BILL));
            String jsonString = JSONObject.toJSONString(vo);
            JSONObject jsonObject = JSONObject.parseObject(jsonString);
            //保存审批记录
            saveApproveInfoProcessor.saveApproveInfo(vo, ContractBusinessEnum.costExemptBill, CaseStatusEnum.UNDER_REVIEW, BusinessUrlEnum.COST_EXEMPT_BILL);
            TaskSubmitVO taskSubmitVO = new TaskSubmitVO();
            taskSubmitVO.setBizData(jsonObject);
            taskSubmitVO.setApprovalOpinion(vo.getApprovalOpinion());
            taskSubmitVO.setApprovalOperating(vo.getApprovalOperating());
            taskSubmitVO.setReasonType(vo.getReasonType());
            workflowSubmitService.submit(taskSubmitVO);
        }
    }

    @Override
    public boolean saveProposalApplicationInfo(CostExemptBillManageVo vo) {
        Boolean flag = false;
        CaseStatusEnum caseStatusEnum = null;
        ProcessStatusEnum processStatusEnum = null;
        if (AfsEnumUtil.key(NormalSubmitEnum.SUGGEST_CHECK_FINAL).equals(vo.getApprovalOperating())) {
            WorkTaskCreatedInfo workTaskCreatedInfo = workTaskCreatedInfoService.getOne(Wrappers.<WorkTaskCreatedInfo>query().lambda()
                    .eq(WorkTaskCreatedInfo::getBizDataId, vo.getId().toString()).orderByDesc(WorkTaskCreatedInfo::getCreateTime), false
            );
            if (ProcessStatusEnum.approved.name().equals(workTaskCreatedInfo.getTaskMemo())) {
                vo.setEndDate(DateUtil.date());
                caseStatusEnum = CaseStatusEnum.APPROVED;
                processStatusEnum = ProcessStatusEnum.approved;
                vo.setStatus(CostExemptBillStatusEnum.effect);

            } else {
                caseStatusEnum = CaseStatusEnum.UNDER_REVIEW;
                processStatusEnum = ProcessStatusEnum.underReview;
                vo.setStatus(CostExemptBillStatusEnum.approval);
            }
            vo.setProcessStatus(processStatusEnum);

            saveApproveInfoProcessor.saveApproveInfo(vo, ContractBusinessEnum.costExemptBill, caseStatusEnum, BusinessUrlEnum.COST_EXEMPT_BILL);
        } else if (AfsEnumUtil.key(NormalSubmitEnum.SUGGEST_REJECT_FINAL).equals(vo.getApprovalOperating())) {
            vo.setEndDate(DateUtil.date());
            vo.setProcessStatus(ProcessStatusEnum.refuse);
            vo.setStatus(CostExemptBillStatusEnum.refuse);
            saveApproveInfoProcessor.saveApproveInfo(vo, ContractBusinessEnum.costExemptBill, CaseStatusEnum.REFUSE, BusinessUrlEnum.COST_EXEMPT_BILL);
        } else if (AfsEnumUtil.key(NormalSubmitEnum.SEND_BACK).equals(vo.getApprovalOperating())) {
            vo.setEndDate(DateUtil.date());
            vo.setProcessStatus(ProcessStatusEnum.toBeRepaired);
            vo.setStatus(CostExemptBillStatusEnum.invalid);
            saveApproveInfoProcessor.saveApproveInfo(vo, ContractBusinessEnum.costExemptBill, CaseStatusEnum.NOT_SUBMIT, BusinessUrlEnum.COST_EXEMPT_BILL);
        }
        updateById(vo);
        List<ManageCostExemptBill> manageCostExemptBills = list(Wrappers.<ManageCostExemptBill>query().lambda()
                .eq(ManageCostExemptBill::getContractNo, vo.getContractNo())
                .eq(ManageCostExemptBill::getStatus,CostExemptBillStatusEnum.effect)
                .orderByAsc(ManageCostExemptBill::getEndDate)
        );
        if (EmptyUtils.isNotEmpty(manageCostExemptBills)&&manageCostExemptBills.size()==2){
            ManageCostExemptBill manageCostExemptBill = manageCostExemptBills.get(0);
            manageCostExemptBill.setStatus(CostExemptBillStatusEnum.failure);
            updateById(manageCostExemptBill);
        }
        String jsonString = JSONObject.toJSONString(vo);
        JSONObject jsonObject = JSONObject.parseObject(jsonString);
        TaskSubmitVO taskSubmitVO = new TaskSubmitVO();
        taskSubmitVO.setBizData(jsonObject);
        taskSubmitVO.setApprovalOperating(vo.getApprovalOperating());
        taskSubmitVO.setApprovalOpinion(vo.getApprovalOpinion());
        taskSubmitVO.setReasonType(vo.getReasonType());
        workflowSubmitService.submit(taskSubmitVO);
        return flag;
    }

    @Override
    public IPage getCostExemptBill(Page page, CostExemptBillManageVo vo) {

        return this.baseMapper.getCostExemptBill(page,vo);
    }
}
